/*
 *   Copyright (c) 2018. 刘路 All rights reserved
 *   版权所有 刘路 并保留所有权利 2018.
 *   ===============================================================
 *   这不是一个自由软件！您只能在不用于商业目的的前提下对程序代码进行修改和
 *   使用。不允许对程序代码以任何形式任何目的的再发布。如果项目发布携带作者
 *   认可的特殊 LICENSE 则按照 LICENSE 执行，废除上面内容。请保留原作者信息。
 *   ================================================================
 *   刘路（feedback@zhoyq.com）于 2018. 创建
 *   http://zhoyq.com
 */

package com.zhoyq.helper.map;

import com.zhoyq.helper.CoordSys;
import com.zhoyq.helper.DataCrawlingHelper;
import com.zhoyq.helper.HttpMethod;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.util.HashMap;
import java.util.Map;

/**
 * 高德服务接口
 * 免费版
 */
public class AMapHelper {

  /**
   * 地图服务的key
   */
  private static String webServiceKey = "";
  private final static String transLnglatUrl = "http://restapi.amap.com/v3/assistant/coordinate/convert";
  private final static String ipPositionUrl = "http://restapi.amap.com/v3/ip";
  private final static String geocodeUrl = "http://restapi.amap.com/v3/geocode/geo";
  private final static String regeocodeUrl = "http://restapi.amap.com/v3/geocode/regeo";
  private final static String searchUrl="http://restapi.amap.com/v3/assistant/inputtips";
  /**
   * 配置项 用于全局配置
   * 这个配置整个应用只配置一次就够了
   * 必须先初始化key在调用这个帮助类
   * @param key 
   */
  public final static void key(String key){
    webServiceKey = key;
  }
  /**
   * 获取参数
   * @return
   */
  private final static Map<String,String> newParams(){
    Map<String,String> params = new HashMap<String,String>();
    params.put("key", webServiceKey);
    params.put("output", "json");
    return params;
  } 
  
  /**
   * 关键字查询
   * 单个key支持1000次/天调用
   * @param keyword
   * @param lnglat 经度,纬度
   * @return 名称|区域|经度,纬度|地址;名称|区域|经度,纬度|地址
   */
  public final static String search(String keyword,String lnglat){
    Map<String,String> params = newParams();
    params.put("keywords", keyword);
    params.put("location", lnglat);
    String json = DataCrawlingHelper.getData(searchUrl, params, HttpMethod.GET, "UTF-8");
    JSONObject jsonObj = JSONObject.parseObject(json);
    if(jsonObj.getString("status").equals("1")){
      JSONArray jsonArr = jsonObj.getJSONArray("tips");
      StringBuilder res = new StringBuilder();
      for(int i = 0;i<jsonArr.size();i++){
        JSONObject obj = jsonArr.getJSONObject(i);
        String name = obj.getString("name");
        String district = obj.getString("district");
        String objlnglat = obj.getString("location");
        String addr = obj.getString("address");
        if(!objlnglat.equals("[]")){
          res.append(name).append("|").append(district).append("|").append(objlnglat).append("|").append(addr).append(";");
        }
      }
      return res.toString();
    }  
    return null; 
  }
  
  
  
  /**
   * 地理编码查询
   * 单个key支持2000次/天调用
   * @param address  省+市+区+街道+门牌号
   * @return 116.397499,39.908722
   */
  public final static String geocode(String address){
    Map<String,String> params = newParams();
    params.put("address", address);
    String json = DataCrawlingHelper.getData(geocodeUrl, params, HttpMethod.GET, "UTF-8");
    JSONObject jsonObj = JSONObject.parseObject(json);
    if(jsonObj.getString("status").equals("1")){
      JSONArray jsonArr = jsonObj.getJSONArray("geocodes");
      if(jsonArr.size()>=1){
        JSONObject res = jsonArr.getJSONObject(0);
        return res.getString("location");
      } 
    }  
    return null;
  }
  
  /**
   * 逆地理编码查询
   * 单个key支持2000次/天调用
   * @param lnglat 例：<code>116.397499,39.908722</code>
   * @return 地址
   */
  public final static String regeocode(String lnglat){
    Map<String,String> params = newParams();
    params.put("location", lnglat);
    params.put("radius", "1000");
    params.put("extensions", "base");
    String json = DataCrawlingHelper.getData(regeocodeUrl, params, HttpMethod.GET, "UTF-8");
    JSONObject jsonObj = JSONObject.parseObject(json);
    if(jsonObj.getString("status").equals("1")){
      JSONObject res = jsonObj.getJSONObject("regeocode");
      return res.getString("formatted_address");
    }  
    return null;
  }
  
  /**
   * 通过ip获得地址 精确到城市
   * 单key支持10000次每分钟
   * @param ip
   * @return 省市描述
   */
  public final static String ipPosition(String ip){
    Map<String,String> params = newParams(); 
    params.put("ip", ip); 
    String json = DataCrawlingHelper.getData(ipPositionUrl, params, HttpMethod.GET, "UTF-8");
    JSONObject jsonObj = JSONObject.parseObject(json);
    if(jsonObj.getString("status").equals("1")){
      String res = jsonObj.getString("province")+jsonObj.getString("city");
      if(res.equals("[][]")){
        return null;
      }else{
        return res;
      }
    }else{
      return null;
    } 
  }
  
  /**
   * 通过ip获得经纬度范围  
   * 单key支持10000次每分钟
   * @param ip
   * @return 107.2936392,40.69877942;107.5177431,40.81327331
   */
  public final static String ipRectangle(String ip){
    Map<String,String> params = newParams(); 
    params.put("ip", ip); 
    String json = DataCrawlingHelper.getData(ipPositionUrl, params, HttpMethod.GET, "UTF-8");
    JSONObject jsonObj = JSONObject.parseObject(json);
    if(jsonObj.getString("status").equals("1")){
      String res = jsonObj.getString("rectangle");
      if(res.equals("[]")){
        return null;
      }else{
        return res;
      }
    }else{
      return null;
    } 
  } 

  /**
   * 为了使用高德服务，用户需要将非高德坐标转换为高德坐标。
   * 单key支持 60000次每分钟
   * 
   * @param locations 经度和纬度用","分割，经度在前，纬度在后，经纬度小数点后不
   *                  得超过6位。多个坐标对之间用”;”进行分隔最多支持40对坐标。
   *                  经纬度必须是六位小数。
   * 
   * @param coordsys  可选值：gps;mapbar;baidu
   * @return
   */ 
  public final static String transLnglat(String locations,CoordSys coordsys){
    String coor = "gps";
    switch(coordsys){
      case GPS:
        coor = "gps";
        break;
      case MAPBAR:
        coor = "mapbar";
        break;
      case BAIDU:
        coor = "baidu";
        break;
    }
    Map<String,String> params = newParams();
    params.put("locations", locations);
    params.put("coordsys", coor);
    String json = DataCrawlingHelper.getData(transLnglatUrl, params, HttpMethod.GET, "UTF-8");
    JSONObject jsonObj = JSONObject.parseObject(json);
    if(jsonObj.getString("status").equals("1")){
      return jsonObj.getString("locations");
    }else{
      return null;
    } 
  } 
}
